﻿using CandidateManager.Areas.Coach.Models;
using System.Collections.Generic;
using System.Web.Mvc;
using WI.CandidateManager.Business.Objects;
using WI.CandidateManager.Common.Data.Entities;

namespace CandidateManager.Areas.Coach.Controllers
{
    /// <summary>
    /// Controller for working with Tests.
    /// </summary>
    public class TestsController : CandidateManager.Controllers.AutorizeBaseController
    {
        #region Test actions

        /// <summary>
        /// Display table with list of own Tests.
        /// </summary>
        /// <returns>Table with list of own Tests</returns>
        [Authorize]
        public ActionResult List()
        {
            TestBO testBO = new TestBO();

            return View(testBO.GetTestList());
        }

        /// <summary>
        /// Display table with list of All Tests.
        /// </summary>
        /// <returns>Table with list of All Tests</returns>
        [Authorize]
        public ActionResult AllList()
        {
            TestBO testBO = new TestBO();

            return View(testBO.GetAllTestList());
        }

        /// <summary>
        /// Display table with list of Pending Tests.
        /// </summary>
        /// <returns>Table with list of Pending Tests</returns>
        [Authorize]
        public ActionResult PendingList()
        {
            TestBO testBO = new TestBO();

            return View(testBO.GetPendingTestList());
        }

        /// <summary>
        /// Get object of Test for displaying details.
        /// </summary>
        /// <param name="TestId">Test id.</param>
        /// <returns>View of Test.</returns>
        [Authorize]
        public ActionResult Detail(long TestId)
        {
            TestBO testBO = new TestBO();

            return View(testBO.GetTest(TestId));
        }

        /// <summary>
        /// Get object of Test for checking.
        /// </summary>
        /// <param name="TestId">Test id.</param>
        /// <returns>View of Test.</returns>
        [Authorize]
        public ActionResult Check(long TestId)
        {
            return View();
        }

        /// <summary>
        /// Display page for creating new Test.
        /// </summary>
        /// <returns>Page for creating new Test.</returns>
        [HttpGet]
        [Authorize]
        public ActionResult Create()
        {
            Test newTest = new Test();

            return View(newTest);
        }

        /// <summary>
        /// Send object of Test to logic for creating.
        /// </summary>
        /// <param name="test">Object of Test.</param>
        /// <returns></returns>
        [HttpPost]
        [Authorize]
        public ActionResult Create(Test test)
        {
            TestBO testBO = new TestBO();

            if (testBO.CreateNewTest(test))
            {
                return RedirectToAction("List", "Tests");
            }
            else
            {
                return View(test);
            }
        }

        /// <summary>
        /// Get model of Test for editing.
        /// </summary>
        /// <param name="TestId">Test id.</param>
        /// <returns>View of Test for editing.</returns>
        [HttpGet]
        [Authorize]
        public ActionResult Edit(long TestId)
        {
            TestBO testBO = new TestBO();
            var test = testBO.GetTest(TestId);

            return View(test);
        }

        /// <summary>
        /// Send object of Test to logic for editing.
        /// </summary>
        /// <param name="TestId">Test id.</param>
        /// <param name="test">Object of Test.</param>
        /// <returns></returns>
        [HttpPost]
        [Authorize]
        public ActionResult Edit(long TestId, Test test)
        {
            TestBO testBO = new TestBO();
            var curTest = testBO.GetTest(TestId);

            if (testBO.ChangeTest(TestId, test))
            {
                return RedirectToAction("List", "Tests");
            }

            return View(curTest);
        }

        /// <summary>
        /// Get model of Test for deleting.
        /// </summary>
        /// <param name="TestId">Test id.</param>
        /// <returns></returns>
        [HttpGet]
        [Authorize]
        public ActionResult Delete(long TestId)
        {
            TestBO testBO = new TestBO();

            return View(testBO.GetTest(TestId));
        }

        /// <summary>
        /// Send object of Test to logic for deleting.
        /// </summary>
        /// <param name="TestId">Test id.</param>
        /// <returns></returns>
        [HttpPost, ActionName("Delete")]
        [Authorize]
        public ActionResult DeleteConfirmed(long TestId)
        {
            TestBO testBO = new TestBO();

            if (testBO.DeleteTest(TestId))
            {
                return RedirectToAction("List", "Tests");
            }

            return View(TestId);
        }

        #endregion

        #region Question actions

        /// <summary>
        /// Get object of Question for displaying details.
        /// </summary>
        /// <param name="QuestionId">Question id.</param>
        /// <returns>View of Question.</returns>
        [Authorize]
        public ActionResult DetailQuestion(long QuestionId)
        {
            TestBO testBO = new TestBO();

            return View(testBO.GetQuestion(QuestionId));
        }

        /// <summary>
        /// Display page for creating new Question.
        /// </summary>
        /// <param name="TestId">Parent test id.</param>
        /// <returns>Page for creating new Question.</returns>
        [HttpGet]
        [Authorize]
        public ActionResult CreateQuestion(long TestId)
        {
            TestBO testBO = new TestBO();

            var question = testBO.GetNewQuestion(TestId);

            return View(question);
        }

        /// <summary>
        /// Send object of Question to logic for creating.
        /// </summary>
        /// <param name="TestId">Parent test id.</param>
        /// <param name="question">Object of Question.</param>
        /// <returns></returns>
        [HttpPost]
        [Authorize]
        public ActionResult CreateQuestion(long TestId, SingleQuestion question)
        {
            TestBO testBO = new TestBO();

            if (testBO.CreateNewQuestion(TestId, question))
            {
                return RedirectToAction("Edit", "Tests", new { TestId = question.Test.Id });
            }
            else
            {
                return View(question);
            }
        }

        /// <summary>
        /// Get model of Question for editing.
        /// </summary>
        /// <param name="QuestionId">Question id.</param>
        /// <returns>View of Question for editing.</returns>
        [HttpGet]
        [Authorize]
        public ActionResult EditQuestion(long QuestionId)
        {
            TestBO testBO = new TestBO();

            return View(testBO.GetQuestion(QuestionId));
        }

        /// <summary>
        /// Send object of Question to logic for editing.
        /// </summary>
        /// <param name="QuestionId">Question id.</param>
        /// <param name="question">Object of Question.</param>
        /// <returns></returns>
        [HttpPost]
        [Authorize]
        public ActionResult EditQuestion(long QuestionId, SingleQuestion question)
        {
            TestBO testBO = new TestBO();
            var curQuestion = testBO.GetQuestion(QuestionId);

            if (testBO.ChangeQuestion(QuestionId, question))
            {
                return RedirectToAction("Edit", "Tests", new { TestId = curQuestion.Test.Id });
            }

            return View(curQuestion);
        }

        /// <summary>
        /// Get model of Question for deleting.
        /// </summary>
        /// <param name="QuestionId">Question id.</param>
        /// <returns></returns>
        [HttpGet]
        [Authorize]
        public ActionResult DeleteQuestion(long QuestionId)
        {
            TestBO testBO = new TestBO();

            return View(testBO.GetQuestion(QuestionId));
        }

        /// <summary>
        /// Send object of Question to logic for deleting.
        /// </summary>
        /// <param name="QuestionId">Question id.</param>
        /// <returns></returns>
        [HttpPost, ActionName("DeleteQuestion")]
        [Authorize]
        public ActionResult DeleteQuestionConfirmed(long QuestionId)
        {
            TestBO testBO = new TestBO();
            var curQuestion = testBO.GetQuestion(QuestionId);
            var parentId = curQuestion.Test.Id;

            if (testBO.DeleteQuestion(QuestionId))
            {
                return RedirectToAction("Edit", "Tests", new { TestId = parentId });
            }

            return View(QuestionId);
        }

        #endregion

        #region Answer actions

        /// <summary>
        /// Display page for creating new Single Answer.
        /// </summary>
        /// <param name="QuestionId">Parent Question id.</param>
        /// <returns>Page for creating new Single Answer.</returns>
        [HttpGet]
        [Authorize]
        public ActionResult CreateSingleAnswer(long QuestionId)
        {
            TestBO testBO = new TestBO();

            var answer = testBO.GetNewSingleAnswer(QuestionId);

            return View(answer);
        }

        /// <summary>
        /// Send object of Single Answer to logic for creating.
        /// </summary>
        /// <param name="QuestionId">Parent Question id.</param>
        /// <param name="answer">Object of Single Answer.</param>
        /// <returns></returns>
        [HttpPost]
        [Authorize]
        public ActionResult CreateSingleAnswer(long QuestionId, SingleAnswer answer)
        {
            TestBO testBO = new TestBO();

            if (testBO.CreateNewSingleAnswer(QuestionId, answer))
            {
                return RedirectToAction("EditQuestion", "Tests", new { QuestionId = answer.QuestionBase.Id });
            }
            else
            {
                return View(answer);
            }
        }

        /// <summary>
        /// Display page for creating new FreeText Answer.
        /// </summary>
        /// <param name="QuestionId">Parent Question id.</param>
        /// <returns>Page for creating new FreeText Answer.</returns>
        [HttpGet]
        [Authorize]
        public ActionResult CreateFreeTextAnswer(long QuestionId)
        {
            TestBO testBO = new TestBO();

            var answer = testBO.GetNewFreeTextAnswer(QuestionId);

            return View(answer);
        }

        /// <summary>
        /// Send object of FreeText Answer to logic for creating.
        /// </summary>
        /// <param name="QuestionId">Parent Question id.</param>
        /// <param name="answer">Object of FreeText Answer.</param>
        /// <returns></returns>
        [HttpPost]
        [Authorize]
        public ActionResult CreateFreeTextAnswer(long QuestionId, FreeTextAnswer answer)
        {
            TestBO testBO = new TestBO();

            if (testBO.CreateNewFreeTextAnswer(QuestionId, answer))
            {
                return RedirectToAction("EditQuestion", "Tests", new { QuestionId = answer.QuestionBase.Id });
            }
            else
            {
                return View(answer);
            }
        }

        /// <summary>
        /// Redirect to specific action for editing.
        /// </summary>
        /// <param name="AnswerId">Answer id.</param>
        /// <returns></returns>
        [Authorize]
        public ActionResult EditAnswer(long AnswerId)
        {
            TestBO testBO = new TestBO();
            var answer = testBO.GetAnswer(AnswerId);

            if (answer is SingleAnswer)
            {
                return RedirectToAction("EditSingleAnswer", "Tests", new { AnswerId = AnswerId });
            }
            else if (answer is FreeTextAnswer)
            {
                return RedirectToAction("EditFreeTextAnswer", "Tests", new { AnswerId = AnswerId });
            }

            return RedirectToAction("EditQuestion", "Tests", new { @QuestionId = answer.QuestionBase.Id });
        }

        /// <summary>
        /// Get model of Single Answer for editing.
        /// </summary>
        /// <param name="AnswerId">Answer id.</param>
        /// <returns>View of Single Answer for editing.</returns>
        [HttpGet]
        [Authorize]
        public ActionResult EditSingleAnswer(long AnswerId)
        {
            TestBO testBO = new TestBO();

            return View(testBO.GetAnswer(AnswerId));
        }

        /// <summary>
        /// Send object of Single Answer to logic for editing.
        /// </summary>
        /// <param name="AnswerId">Answer id.</param>
        /// <param name="answer">Object of Single Answer.</param>
        /// <returns></returns>
        [HttpPost]
        [Authorize]
        public ActionResult EditSingleAnswer(long AnswerId, SingleAnswer answer)
        {
            TestBO testBO = new TestBO();
            var curAnswer = testBO.GetAnswer(AnswerId);

            if (testBO.ChangeSingleAnswer(AnswerId, answer))
            {
                return RedirectToAction("EditQuestion", "Tests", new { QuestionId = curAnswer.QuestionBase.Id });
            }

            return View(curAnswer);
        }

        /// <summary>
        /// Get model of FreeText Answer for editing.
        /// </summary>
        /// <param name="AnswerId">Answer id.</param>
        /// <returns>View of FreeText Answer for editing.</returns>
        [HttpGet]
        [Authorize]
        public ActionResult EditFreeTextAnswer(long AnswerId)
        {
            TestBO testBO = new TestBO();

            return View(testBO.GetAnswer(AnswerId));
        }

        /// <summary>
        /// Send object of Single Answer to logic for editing.
        /// </summary>
        /// <param name="AnswerId">Answer id.</param>
        /// <param name="answer">Object of Single Answer.</param>
        /// <returns></returns>
        [HttpPost]
        [Authorize]
        public ActionResult EditFreeTextAnswer(long AnswerId, FreeTextAnswer answer)
        {
            TestBO testBO = new TestBO();
            var curAnswer = testBO.GetAnswer(AnswerId);

            if (testBO.ChangeFreeTextAnswer(AnswerId, answer))
            {
                return RedirectToAction("EditQuestion", "Tests", new { QuestionId = curAnswer.QuestionBase.Id });
            }

            return View(curAnswer);
        }

        /// <summary>
        /// Get model of Answer for deleting.
        /// </summary>
        /// <param name="AnswerId">Answer id.</param>
        /// <returns></returns>
        [HttpGet]
        [Authorize]
        public ActionResult DeleteAnswer(long AnswerId)
        {
            TestBO testBO = new TestBO();

            return View(testBO.GetAnswer(AnswerId));
        }

        /// <summary>
        /// Send object of Answer to logic for deleting.
        /// </summary>
        /// <param name="AnswerId">Answer id.</param>
        /// <returns></returns>
        [HttpPost, ActionName("DeleteAnswer")]
        [Authorize]
        public ActionResult DeleteAnswerConfirmed(long AnswerId)
        {
            TestBO testBO = new TestBO();
            var curAnswer = testBO.GetAnswer(AnswerId);
            var parentId = curAnswer.QuestionBase.Id;

            if (testBO.DeleteAnswer(AnswerId))
            {
                return RedirectToAction("EditQuestion", "Tests", new { QuestionId = parentId });
            }

            return View(curAnswer);
        }

        #endregion

        #region Assign actions


        [Authorize]
        public ActionResult Assign(long TestId)
        {
            TestBO testBO = new TestBO();

            return View(testBO.GetTest(TestId));
        }


        [Authorize]
        public ActionResult RemoveCandidate(long CandidateId, long TestId)
        {
            CoachBO coachBO = new CoachBO();

            coachBO.DeassingTaskToCandidate(TestId, CandidateId);

            return RedirectToAction("Assign", "Tests", new { TestID = TestId });
        }


        [Authorize]
        [HttpGet]
        public ActionResult AssignToGroups(long TestId)
        {
            CoachBO coachBO = new CoachBO();
            TestBO testBO = new TestBO();

            var groups = coachBO.GetGroups();
            GroupAssignModel groupAssignModel = new GroupAssignModel();
            groupAssignModel.Task = testBO.GetTest(TestId);
            groupAssignModel.GroupCheckList = new List<GroupChecklistModel>();
            
            groupAssignModel.Task = testBO.GetTest(TestId);
            foreach (var group in groups)
            {
                groupAssignModel.GroupCheckList.Add(new GroupChecklistModel() { IsChecked = false, Group = group, GroupId = group.Id });
            }

            return View(groupAssignModel);
        }

        [Authorize]
        [HttpPost]
        public ActionResult AssignToGroups(long TaskId, GroupAssignModel groupAssignModel)
        {
            CoachBO coachBO = new CoachBO();

            foreach (var group in groupAssignModel.GroupCheckList)
            {
                if (group.IsChecked)
                {
                    coachBO.AssignTaskToGroup(TaskId, group.GroupId);
                }
            }

            return RedirectToAction("Assign", "Tests", new { TestId = TaskId });
        }

        [Authorize]
        [HttpGet]
        public ActionResult AssignToCandidates(long TestId)
        {
            CoachBO coachBO = new CoachBO();
            TestBO testBO = new TestBO();

            var candidates = coachBO.GetCoachesCandidates();
            CandidateAssignModel candidateAssignModel = new CandidateAssignModel();
            candidateAssignModel.Task = testBO.GetTest(TestId);
            candidateAssignModel.CandidateCheckList = new List<CandidateChecklistModel>();

            foreach (var candidate in candidates)
            {
                candidateAssignModel.CandidateCheckList.Add(new CandidateChecklistModel() { CandidateId = candidate.Id, IsChecked = false, Candidate = candidate });
            }

            return View(candidateAssignModel);
        }

        [Authorize]
        [HttpPost]
        public ActionResult AssignToCandidates(long TaskId, CandidateAssignModel candidateAssignModel)
        {
            CoachBO coachBO = new CoachBO();

            foreach (var candidate in candidateAssignModel.CandidateCheckList)
            {
                if (candidate.IsChecked)
                {
                    coachBO.AssignTaskToCandidate(TaskId, candidate.CandidateId);
                }
            }

            return RedirectToAction("Assign", "Tests", new { TestID = TaskId });
        }

        #endregion
    }
}